#ifndef GO_GENERATOR_H
#define GO_GENERATOR_H

#include "code_generator.h"

#include <fstream>
#include <map>
#include <set>

namespace pp
{
    class GoGenerator : public CodeGenerator
    {
    private:
        std::string m_sGoPackage;                               // go package
        std::set<std::string> m_oEnumList;                      // 枚举，key: package.enumName
        std::map<std::string, std::string> m_oStructMap;        // 结构体，key: package.structName => package.newStructName
    public:
        GoGenerator(const std::string& srcdir, const std::string& outdir) : CodeGenerator(srcdir, outdir) {}
    public:
        // 重置数据
        virtual void Reset(const std::string& srcfile); // srcfile是pp定义文件名
        // 处理pp文件中的import定义
        virtual void HandleImport(const std::string& imports);
        // 处理pp文件中的option定义，忽略不支持的option。比如option go_package是一个option
        virtual void HandleOption(const std::string& name, const std::string& value);
        // 处理pp文件中的常量定义
        virtual void HandleConst(const std::shared_ptr<FieldInfo>& fieldInfo);
        // 处理pp文件中的enum定义
        virtual void HandleEnum(const std::shared_ptr<StructInfo>& structInfo);
        // 处理pp文件中的message定义
        virtual void HandleStruct(const std::shared_ptr<StructInfo>& structInfo);
        // 生成文件
        virtual void Generate();
    protected:
        // 包名称
        const std::string& GetGoPackage() const {return m_sGoPackage;}
        // 返回类成员定义
        std::string GetStructType(const std::string& ftype, const std::string& subtype);
        std::string GetImportValue(const std::string& ftype);
        // 类型
        static std::string GetGoType(const std::string& ppType);
    protected:
        // 生成go文件内容
        void GenerateGoFile(const std::string& outdir, const std::string& filename);
        // 生成import
        void GenerateImport(std::ofstream& ofs);
        // 生成常量定义
        void GenerateConst(std::ofstream& ofs);
        // 生成枚举定义
        void GenerateEnum(std::ofstream& ofs);
        // 生成枚举值
        void GenerateEnumValues(std::ofstream& ofs, const std::string& enumName, const std::vector<std::shared_ptr<FieldInfo> >& vals);
        // 生成结构体定义
        void GenerateStruct(std::ofstream& ofs);
        // 生成结构体成员定义
        void GenerateStructAttributes(std::ofstream& ofs, const std::vector<std::shared_ptr<FieldInfo> >& vals);
        // 生成结构体New定义
        void GenerateStructNewFunction(std::ofstream& ofs, const std::string& structName, bool bUnion, const std::vector<std::shared_ptr<FieldInfo> >& vals);
        // 生成结构体成员Get定义
        void GenerateStructGetFunctions(std::ofstream& ofs, const std::string& structName, const std::vector<std::shared_ptr<FieldInfo> >& vals);
        // 生成结构体成员Marshal定义
        void GenerateStructMarshal(std::ofstream& ofs, const std::string& structName, const std::vector<std::shared_ptr<FieldInfo> >& vals);
        // 生成结构体成员UnMarshal定义
        void GenerateStructUnMarshal(std::ofstream& ofs, const std::string& structName, const std::vector<std::shared_ptr<FieldInfo> >& vals);
    };
};

#endif
